package com.yangtao.framework.plugin.poi;

import net.sf.jxls.transformer.XLSTransformer;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @auther: 杨涛
 * Date: 11-5-13
 * Time: 下午12:35
 * @version: 1.0
 */
public class JxlsHelper {
	private static Logger logger = LoggerFactory.getLogger(JxlsHelper.class);

	/**
	 * 根据输出流和输入流写内容
	 *
	 * @param outputStream     输出流
	 * @param inputStream      输入流
	 * @param hiddenProperties 需要隐藏的属性
	 * @param data             模板的数据模型
	 * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException
	 *
	 * @throws java.io.IOException
	 */
	private static void render(OutputStream outputStream, InputStream inputStream, String[] hiddenProperties, Map<String, Object> data)
			throws InvalidFormatException, IOException {
		XLSTransformer transformer = new XLSTransformer();
		Map<String, Object> model = new HashMap<String, Object>();
		if (data != null) {
			model.putAll(data);
		}
		if (hiddenProperties != null && hiddenProperties.length > 0) {
			transformer.setColumnPropertyNamesToHide(hiddenProperties);
		}
		Workbook workbook = transformer.transformXLS(inputStream, model);
		workbook.write(outputStream);
	}

	/**
	 * 根据输出流和模板文件，向输出流中写内容
	 *
	 * @param outputStream     输出流
	 * @param template         模板文件
	 * @param hiddenProperties 需要隐藏的属性
	 * @param data             模板的数据模型
	 */
	public static void render(OutputStream outputStream, File template, String[] hiddenProperties, Map<String, Object> data) {
		FileInputStream fileInputStream = null;
		try {
			fileInputStream = new FileInputStream(template);
			render(outputStream, fileInputStream, hiddenProperties, data);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage(), e);
		} finally {
			//关闭文件流
			if (fileInputStream != null) {
				try {
					fileInputStream.close();
				} catch (IOException e) {
					fileInputStream = null;
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 根据输出流和模板文件，向输出流中写内容
	 *
	 * @param outputStream 输出流
	 * @param template     模板文件
	 * @param data         模板的数据模型
	 */
	public static void render(OutputStream outputStream, File template, Map<String, Object> data) {
		render(outputStream, template, null, data);
	}

	/**
	 * 根据模板文件和目标文件名称生成目标文件
	 *
	 * @param targetFileName   目标文件名称
	 * @param templateFileName 模板文件名称
	 * @param hiddenProperties 需要隐藏的属性
	 * @param data             数据
	 */
	public static void render(String targetFileName, String templateFileName, String[] hiddenProperties, Map<String, Object> data) {
		File targetFile = new File(targetFileName);
		File templateFile = new File(templateFileName);
		if (targetFile.exists()) {
			throw new RuntimeException("目标文件已经存在！");
		}
		if (!templateFile.exists()) {
			throw new RuntimeException("模板文件不存在！");
		}
		FileOutputStream fos = null;
		FileInputStream fis = null;
		try {
			fos = new FileOutputStream(targetFile);
			fis = new FileInputStream(templateFile);
			render(fos, fis, hiddenProperties, data);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage(), e);
		} finally {
			//关闭输入，输出流
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					fos = null;
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					fis = null;
				}
			}
		}
	}

	/**
	 * 根据模板文件和目标文件名称生成目标文件
	 *
	 * @param targetFileName   目标文件名称
	 * @param templateFileName 模板文件名称
	 * @param data             数据
	 */
	public static void render(String targetFileName, String templateFileName, Map<String, Object> data) {
		render(targetFileName, templateFileName, null, data);
	}

	/**
	 * 向response中写入下载的文件
	 *
	 * @param fileName         下载文件的名称
	 * @param response         httpresponse
	 * @param template         模板文件
	 * @param hiddenProperties 需要隐藏的属性
	 * @param data             模板对应的数据
	 */
	public static void render(String fileName, HttpServletResponse response, File template, String[] hiddenProperties, Map<String, Object> data) {
		if (StringUtils.isEmpty(fileName)) {
			throw new RuntimeException("文件名称不能为空！");
		}
		response.reset();
		//设置文件类型
		if (template.getName().endsWith(".xls")) {
			response.setContentType("application/vnd.ms-excel");
		} else if (template.getName().endsWith(".xlsx")) {
			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		}
		try {
			fileName = new String(fileName.getBytes(), "ISO8859-1");
			response.setHeader("Content-Disposition",
					"'attachment'; filename=\"" + fileName + "\"");
			OutputStream ouputStream = response.getOutputStream();
			render(ouputStream, template, hiddenProperties, data);
			ouputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage(), e);
		}
	}

	/**
	 * 向response中写入下载的文件
	 *
	 * @param fileName 下载文件的名称
	 * @param response httpresponse
	 * @param template 模板文件
	 * @param data     模板对应的数据
	 */
	public static void render(String fileName, HttpServletResponse response, File template, Map<String, Object> data) {
		render(fileName, response, template, null, data);
	}
}
